const WebpackBar = require('webpackbar');
const BundleAnalyzerPlugin =
  require('webpack-bundle-analyzer').BundleAnalyzerPlugin;
const LodashModuleReplacementPlugin = require('lodash-webpack-plugin');

const path = require('path');

const resolve = dir => path.join(__dirname, dir);
const pkg = require('./package.json');

const IS_DEV = process.env.NODE_ENV !== 'production';
const RELEASE_VERSION = pkg.version;

function devServerProxyOrMock() {
  // 如果是 VUE_APP_API_PROXY 是 https 则需要进行本地反代，如果非https则进行mock
  if (
    process.env.VUE_APP_API_PROXY &&
    (process.env.VUE_APP_API_PROXY.startsWith('https://') ||
      process.env.VUE_APP_API_PROXY.startsWith('http://') ||
      process.env.VUE_APP_API_PROXY.startsWith('//'))
  ) {
    return {
      proxy: {
        '/api': {
          target: process.env.VUE_APP_API_PROXY,
          changeOrigin: true,
          pathRewrite: {
            '^/api': '',
          },
        },
      },
    };
  }
  return {
    before: require('./mocks/server'),
  };
}

/**
 * @todo 开发环境配置
 * 某些实用工具， plugins 和 loaders 都只能在构建生产环境时才有用
 * 在开发时使用 UglifyJsPlugin 来压缩和修改代码是没有意义的,不压缩
 */

const DEVELOPMENT = webpackConfig => {
  // webpackConfig.store.set('devtool', 'eval-source-map');
  webpackConfig.plugin('html').tap(([options]) => [
    Object.assign(options, {
      minify: false,
      chunksSortMode: 'none',
      title: process.env.APP_TITLE,
    }),
  ]);

  // webpackConfig.plugin('BundleAnalyzerPlugin').use(BundleAnalyzerPlugin)

  return webpackConfig;
};

const PRODUCTION = webpackConfig => {
  // webpackConfig.store.set('devtool', '');
  webpackConfig.plugin('html').tap(([options]) => [
    Object.assign(options, {
      minify: {
        removeComments: true,
        removeCommentsFromCDATA: true,
        collapseWhitespace: true,
        conservativeCollapse: false,
        collapseInlineTagWhitespace: true,
        collapseBooleanAttributes: true,
        removeRedundantAttributes: true,
        removeAttributeQuotes: false,
        removeEmptyAttributes: true,
        removeScriptTypeAttributes: true,
        removeStyleLinkTypeAttributes: true,
        useShortDoctype: true,
        minifyJS: true,
        minifyCSS: true,
      },
      cache: true, // 仅在文件被更改时发出文件
      hash: true, // true则将唯一的webpack编译哈希值附加到所有包含的脚本和CSS文件中,这对于清除缓存很有用
      scriptLoading: 'defer', // 现代浏览器支持非阻塞javascript加载（'defer'）,以提高页面启动性能。
      inject: true, // true所有javascript资源都将放置在body元素的底部
      chunksSortMode: 'none',
      title: process.env.APP_TITLE,
    }),
  ]);

  return webpackConfig;
};

module.exports = {
  publicPath: IS_DEV ? '/' : '/',
  css: {
    loaderOptions: {
      less: {
        globalVars: {},
        srouceMap: IS_DEV,
        javascriptEnabled: true,
        lessOptions: {
          javascriptEnabled: true,
        },
      },
    },
  },
  devServer: {
    ...devServerProxyOrMock(),
  },
  pluginOptions: {
    /**
     * @description 全局加载less 的 webpack 插件
     */
    'style-resources-loader': {
      preProcessor: 'scss',
      patterns: ['./src/styles/var.scss'],
      injector: 'prepand',
    },
  },
  /**
   * @description 去掉 console信息
   *  config.optimization.minimizer[0].options.terserOptions.compress.drop_console = true;
   *  html-webpack-plugin插件配置详情见 https://github.com/jantimon/html-webpack-plugin#options
   */
  configureWebpack: config => {
    config.optimization = {
      splitChunks: {
        chunks: 'all',
        minSize: 3000, // （默认值：30000）块的最小大小。
        minChunks: 1, //（默认值：1）在拆分之前共享模块的最小块数
        maxAsyncRequests: 5, //（默认值为5）按需加载时并行请求的最大数量
        maxInitialRequests: 6, // （默认值为3）入口点的最大并行请求数
        automaticNameDelimiter: '-',
        name: true,
        cacheGroups: {
          lodash: {
            name: 'lodash',
            test: /[\\/]node_modules[\\/]lodash[\\/]/,
            priority: 20,
          },
          vue: {
            name: 'vue',
            test: /[\\/]node_modules[\\/]vue[\\/]/,
          },
          vuex: {
            name: 'vuex',
            test: /[\\/]node_modules[\\/]vuex[\\/]/,
          },
          'vue-router': {
            name: 'vue-router',
            test: /[\\/]node_modules[\\/]vue-router[\\/]/,
          },
          'ant-design-vue': {
            name: 'ant-design-vue',
            test: /[\\/]node_modules[\\/]ant-design-vue[\\/]/,
          },
          moment: {
            name: 'moment',
            test: /[\\/]node_modules[\\/]moment[\\/]/,
            priority: 40,
          },
        },
      },
    };

    return {
      plugins: [
        new WebpackBar({
          name: `dev-starter`,
          color: '#f40',
        }),
      ],
    };
  },
  chainWebpack: config => {
    config.resolve.symlinks(true);

    config.module.rule('svg').exclude.add(resolve('src/assets/svgs')).end();

    config.module
      .rule('icons')
      .test(/\.svg$/)
      .include.add(resolve('src/assets/svgs'))
      .end()
      .use('svg-sprite-loader')
      .loader('svg-sprite-loader')
      .options({
        symbolId: 'icon-[name]',
      });

    if (process.env.ASSETS_ANALYSIS) {
      config.plugin('webpack-bundle-analyzer').use(BundleAnalyzerPlugin);
    }

    config.plugin('loadshReplace').use(new LodashModuleReplacementPlugin());

    IS_DEV ? DEVELOPMENT(config) : PRODUCTION(config);
  },
  productionSourceMap: true,
  lintOnSave: true,
};
